import { fetchEventSource } from '@microsoft/fetch-event-source';
//使用fetch-event-source库调用sse公共方法
/**
 *
 * @param {请求地址} fetchUrl
 * @param {signal} signal
 * @param {请求参数} params
 * @param {onopen回调} onopenCallBack
 * @param {onmessage回调} onmessageCallBack
 */
export function eventSourceUtil(fetchUrl, signal, params, onopenCallBack, onmessageCallBack) {
  // 重试相关配置
  const retryConfig = {
    // 初始重试延迟（毫秒）
    initialRetryDelayMs: 1000,
    // 最大重试延迟（毫秒）
    maxRetryDelayMs: 30000,
    // 重试延迟增长因子
    retryBackoffFactor: 1.5,
    // 当前重试次数
    retryCount: 0,
    // 计算下一次重试延迟
    getNextRetryDelayMs() {
      const delay = Math.min(
        this.initialRetryDelayMs * Math.pow(this.retryBackoffFactor, this.retryCount),
        this.maxRetryDelayMs
      );
      this.retryCount++;
      return delay;
    },
    // 重置重试计数
    resetRetryCount() {
      this.retryCount = 0;
    }
  };

  // 是否收到过任何消息
  let hasReceivedMessage = false;
  // 最后一次收到消息的时间
  let lastMessageTime = Date.now();
  // 心跳检测的超时时间（毫秒）
  const heartbeatTimeoutMs = 60000; // 60秒

  // 心跳检测定时器
  let heartbeatCheckTimer = null;

  // 启动心跳检测
  function startHeartbeatCheck() {
    // 清除现有的定时器（如果有）
    if (heartbeatCheckTimer) {
      clearInterval(heartbeatCheckTimer);
    }

    // 设置新的定时器
    heartbeatCheckTimer = setInterval(() => {
      const now = Date.now();
      // 如果超过心跳超时时间没有收到消息，认为连接断开
      if (now - lastMessageTime > heartbeatTimeoutMs && hasReceivedMessage) {
        console.warn('No messages received for too long, connection may be dead');

        // 如果信号未被中止，则中止连接并尝试重新连接
        if (signal && !signal.aborted) {
          const controller = signal.controller;
          if (controller) {
            console.log('Aborting current connection due to heartbeat timeout');
            controller.abort();

            // 在短暂延迟后重新连接
            setTimeout(() => {
              if (!signal.aborted) {
                console.log('Reconnecting after heartbeat timeout...');
                initConnection();
              }
            }, 1000);
          }
        }
      }
    }, 10000); // 每10秒检查一次
  }

  // 停止心跳检测
  function stopHeartbeatCheck() {
    if (heartbeatCheckTimer) {
      clearInterval(heartbeatCheckTimer);
      heartbeatCheckTimer = null;
    }
  }

  // 初始化连接
  function initConnection() {
    fetchEventSource(fetchUrl, {
      ...params,
      signal: signal,
      openWhenHidden: true,
      // 重试策略
      retry: {
        // 判断是否应该重试
        retryStatusCodes: [500, 502, 503, 504],
        // 自定义重试逻辑
        retryDelay: async (attempt, error, response) => {
          // 如果是因为 signal 被中止导致的错误，不要重试
          if (signal && signal.aborted) {
            console.log('Connection aborted, not retrying');
            throw error;
          }

          // 如果服务器明确表示不要重试或者客户端错误，不要重试
          if (response && (response.status < 500 && response.status !== 429)) {
            console.log(`Server returned ${response.status}, not retrying`);
            throw error;
          }

          // 计算重试延迟
          const delayMs = retryConfig.getNextRetryDelayMs();
          console.log(`Retrying connection in ${delayMs}ms (attempt ${retryConfig.retryCount})`);
          return delayMs;
        }
      },
      onopen: (response) => {
        if (response.ok && response.status === 200) {
          console.log('SSE connection established successfully');
          // 重置重试计数
          retryConfig.resetRetryCount();
          // 连接成功后启动心跳检测
          startHeartbeatCheck();
        } else {
          console.error(`Failed to establish SSE connection. Status: ${response.status}`);
        }
        // 调用回调
        if (onopenCallBack) {
          onopenCallBack(response);
        }
      },
      onmessage: (event) => {
        // 更新最后收到消息的时间
        lastMessageTime = Date.now();
        // 标记已收到消息
        hasReceivedMessage = true;

        // 调用回调处理消息
        if (onmessageCallBack) {
          onmessageCallBack(event);
        }
      },
      onclose: () => {
        console.log('SSE connection closed');
        // 停止心跳检测
        stopHeartbeatCheck();
      },
      onerror: (error) => {
        console.error('SSE connection error:', error);

        // 停止心跳检测
        stopHeartbeatCheck();

        if (signal && signal.aborted) {
          console.log('Connection was aborted, not processing error further');
          return;
        }

        if (error instanceof Error) {
          console.error('Error details:', error.message);
        }

        // 抛出错误让重试机制处理
        throw error;
      }
    }).catch(reason => {
      console.info('Connection error caught:', reason);

      // 停止心跳检测
      stopHeartbeatCheck();

      // 如果不是因为用户主动中止，则记录详细错误
      if (!(signal && signal.aborted)) {
        console.error('Connection failed:', reason);
      }
    });
  }

  // 启动连接
  initConnection();
}
